<?php
/**
 * A rowset class.
 */
class Collection implements SeekableIterator, Countable {
    /**
     * The driver to use.
     * @var Database_Driver
     */
    protected $driver = null;
    /**
     * The row pointer.
     * @var int
     */
    private $pointer = 0;
    /**
     * The raw data.
     * @var array
     */
    protected $data = array();
    /**
     * The rows.
     * @var array
     */
    protected $rows = array();
    protected $table = false;
    protected $count = 0;
    protected $readonly = false;
    protected $modelclass = 'Model';
    
    /**
     * Constructor. Set up the driver.
     */
    public function __construct(Database_Driver $driver = null, $data = array()) {
        if($driver) {
            $this->driver = $driver;
        } else {
            $this->driver = Framework::getDefaultDatabase();
        }
        if(!$this->table) {
            $readonly = true;
        }
        $this->data = $data;
    }
    
    /**
     * The number of rows in the set.
     * @return int
     */
    public function count() {
        return $this->count;
    }
    
    /**
     * Reset the pointer.
     */
    public function rewind() {
        $this->pointer = 0;
    }
    
    /**
     * Is the pointer still valid.
     * @return bool
     */
    public function valid() {
        if($this->pointer < $this->count) {
            return true;
        }
        return false;
    }
    
    /**
     * Get the current row. Only retrieve a row once.
     * @return Row
     */
    public function current() {
        if(!$this->valid()) {
            return null;
        }
        if(!isset($this->rows[$this->pointer])) {
            $this->rows[$this->pointer] = new $this->modelclass($this->driver, $this->data[$this->pointer], $this->table);
        }
        return $this->rows[$this->pointer];
    }
    
    /**
     * Get the next row.
     * @return Row
     */
    public function next() {
        $this->pointer++;
        return $this->current();
    }
    
    /**
     * Get the current pointer position.
     * @return int
     */
    public function key() {
        return $this->pointer;
    }
    
    public function seek($index) {
        $this->pointer = $index;
        if(!$this->valid()) {
            throw new OutOfBoundsException('Invalid seek position.');
        }
    }
    
    public function getRow($index) {
        $this->seek($index);
        return $this->current();
    }
    
    protected function setData($data) {
        $this->data = $data;
        $this->count = count($this->data);
    }
    
    public function selectAll() {
        $this->setData($this->driver->selectAll($this->table));
    }
}
?>